// AdvancedScene.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//


#define __ECS_RUNTIME_CORE
#define JOYENGINE_DLL_MODE

//
#include"JE_Basic.h"


#include "AdvancedScene.h"

#include<locale>

#include<time.h>

#include"ascene.h"

void LimitRun(float LimitTime)
{
	while (1)
	{
		auto p = ((double)clock()) / (double)CLOCKS_PER_SEC;
		if (p >= LimitTime) {
			std::cout << "超时结束" << std::endl;
			_Exit(1);
		}
		std::this_thread::yield();
	}
}


// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门提示: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件，或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来，若要再次打开此项目，请转到“文件”>“打开”>“项目”并选择 .sln 文件

//新编译器测试区域
//
//struct ScopeInfomation
//{
//	std::vector<ScopeInfomation*> ChildScope;
//	ScopeInfomation* FatherScope;
//
//	static ScopeInfomation* RootScope;
//};
//ScopeInfomation* ScopeInfomation::RootScope = new ScopeInfomation();
//


//end


inline static ecs::Type::SharedMutex MachineDataLock;
//inline static ecs::Type::ThreadSafeVector<asMachine> MachineList;
inline static ecs::Type::Map< asMachine, std::string> ErrorInfo;
inline static std::string LastErrorInfo;

#define ReadLock ecs::Type::SharedLock<ecs::Type::SharedMutex>Lck(MachineDataLock)
#define WriteLock ecs::Type::SharedLock<ecs::Type::SharedMutex>Lck(MachineDataLock)

asInt ARGC = 0;
char** ARGV = nullptr;


asInt System_GetArgs(asMachine e)
{
	asValue vptr = asArgument(e, 0);

	std::vector<AScene::AllTypeData>* vec = (std::vector<AScene::AllTypeData>*)asGetLong(vptr);

	vec->clear();
	for (auto i = 0; i < ARGC; i++)
	{
		vec->push_back(ARGV[i]);
	}

	return 0;

}
asInt System_GetVersion(asMachine e)
{
	return asReturnString(e, asCopyrightInfo());


}

asInt System_Runtime_FunctionCall(asMachine e)
{
	asMachine mac = (asMachine)asGetLong(asArgument(e, 0));
	asString fname = asGetString(asArgument(e, 1));
	asInt staxn = asGetInt(asArgument(e, 2));

	auto fr = asFunctionRun(mac, fname, staxn);
	if (fr)
		return asReturnValue(e, fr);

	asException(asGetError(mac));
	return 0;
}

asInt System_Native_Malloc(asMachine e)
{
	int Size = asGetInt(asArgument(e, 0));
	auto mptr = malloc(Size);
	memset(mptr, 0, Size);
	return asReturnLong(e, (asLong)mptr);
}
asInt System_Native_Free(asMachine e)
{
	void* Ptr = (void*)asGetLong(asArgument(e, 0));
	free(Ptr);
	return 0;
}
asInt System_Native_Memcpy(asMachine e)
{
	void* Dst = (void*)asGetLong(asArgument(e, 0));
	void* Src = (void*)asGetLong(asArgument(e, 1));
	int Size = asGetInt(asArgument(e, 2));
	memcpy(Dst, Src, Size);
	return 0;
}
asInt System_Native_PhaseInt(asMachine e)
{
	void* Ptr = (void*)asGetLong(asArgument(e, 0));
	//int Offset = asGetInt(asArgument(e, 1));
	return asReturnInt(e, *(int*)Ptr);
}
asInt System_Native_PhaseString(asMachine e)
{
	void* Ptr = (void*)asGetLong(asArgument(e, 0));
	//int Offset = asGetInt(asArgument(e, 1));
	return asReturnString(e, (char*)Ptr);
}
asInt System_Native_PhaseLong(asMachine e)
{
	void* Ptr = (void*)asGetLong(asArgument(e, 0));
	//int Offset = asGetInt(asArgument(e, 1));
	return asReturnLong(e, *(long long*)Ptr);
}
asInt System_Native_PhaseDouble(asMachine e)
{
	void* Ptr = (void*)asGetLong(asArgument(e, 0));
	//int Offset = asGetInt(asArgument(e, 1));
	return asReturnDouble(e, *(double*)Ptr);
}
asInt System_Native_Write(asMachine e)
{
	void* Ptr = (void*)asGetLong(asArgument(e, 0));
	//int Offset = asGetInt(asArgument(e, 1));
	int ByteMsg = asGetInt(asArgument(e, 1));

	*((char*)Ptr) = ByteMsg;
	return 0;

}
asInt System_Rand_UniformRandInt(asMachine e)
{
	static std::random_device rd;
	static std::mt19937 gen(rd());

	std::uniform_int_distribution<> dis
	(asGetInt(asArgument(e, 0)), asGetInt(asArgument(e, 1)));
	return asReturnInt(e, dis(gen));

}
asInt System_Rand_UniformRandDouble(asMachine e)
{
	static std::random_device rd;
	static std::mt19937 gen(rd());

	std::uniform_real_distribution<> dis
	(asGetDouble(asArgument(e, 0)), asGetDouble(asArgument(e, 1)));
	return asReturnDouble(e, dis(gen));

}
asInt System_Thread_Sleep(asMachine e)
{
	using namespace std::chrono;

	std::this_thread::sleep_for(asGetDouble(asArgument(e, 0)) * 1s);

	return 0;
}
asInt System_Thread_CreateMutex(asMachine e)
{
	return asReturnLong(e, (asLong)new std::mutex());
}
asInt System_Thread_DestroyMutex(asMachine e)
{
	delete (std::mutex*)asGetLong(asArgument(e, 0));
	return 0;
}
asInt System_Thread_LockMutex(asMachine e)
{
	((std::mutex*)asGetLong(asArgument(e, 0)))->lock();
	return 0;
}
asInt System_Thread_ReleaseMutex(asMachine e)
{
	((std::mutex*)asGetLong(asArgument(e, 0)))->unlock();
	return 0;
}

asInt System_File_OpenToRead(asMachine e)
{
	auto ptr = new std::ifstream(asGetString(asArgument(e, 0)));
	if (ptr->is_open())
	{
		return asReturnLong(e, (asLong)ptr);
	}
	asException("目标文件无法打开");
	return asReturnLong(e, 0);
}
asInt System_File_ReadLine(asMachine e)
{
	auto ptr = (std::istream*)asGetLong(asArgument(e, 0));
	std::string str;
	std::getline(*ptr, str);
	return asReturnString(e, str.data());
}
asInt System_File_Close(asMachine e)
{
	delete (std::istream*)asGetLong(asArgument(e, 0));
	return 0;
}

asInt System_Json_StringSaveToFile(asMachine e)
{
	asString str = asGetString(asArgument(e, 0));
	asString file = asGetString(asArgument(e, 1));

	std::ofstream fileobj(file);
	if (fileobj.is_open())
	{
		fileobj << str;
		return 0;
	}
	asException("目标文件无法创建或打开");
	return 0;
}

asInt System_Json_FileReadToStr(asMachine e)
{
	asString file = asGetString(asArgument(e, 0));

	std::ifstream fileobj(file);
	if (fileobj.is_open())
	{
		std::stringstream ffinfo;
		ffinfo << (fileobj.rdbuf());
		std::string buf(ffinfo.str());
		return asReturnString(e, buf.c_str());
	}
	asException("目标文件无法打开");

	return 0;
}

asInt System_Set_VmPath(asMachine e)
{
	ecs::Environment::Path::ExeFilePath = asGetString(asArgument(e, 0));
	return 0;
}
#ifdef _WIN32
#include<filesystem>
using namespace std;
#else
#include<experimental/filesystem>
using namespace std::experimental;
#endif
///////////////////////////////////////////////////////////////////////////////////////////////////////
asInt System_FSys_Openpath(asMachine e)
{
	return asReturnLong(e, (asLong)new filesystem::path(asGetString(asArgument(e, 0))));
}
asInt System_FSys_Closepath(asMachine e)
{
	delete (filesystem::path*)asGetLong(asArgument(e, 0));
	return 0;
}

asInt System_FSys_ToString(asMachine e)
{
	auto ptr = (filesystem::path*)asGetLong(asArgument(e, 0));
	return asReturnString(e, ptr->string().c_str());
}
asInt System_FSys_CreateDirectory(asMachine e)
{
	auto ptr = (filesystem::path*)asGetLong(asArgument(e, 0));
	filesystem::create_directory(*ptr);
	return 0;
}
asInt System_FSys_Exists(asMachine e)
{
	auto ptr = (filesystem::path*)asGetLong(asArgument(e, 0));
	return asReturnInt(e, filesystem::exists(*ptr));
}
asInt System_FSys_Copy(asMachine e)
{
	auto ptr = (filesystem::path*)asGetLong(asArgument(e, 0));
	auto ptrto = (filesystem::path*)asGetLong(asArgument(e, 1));
	filesystem::copy(*ptr, *ptrto);
	return 0;
}
asInt System_FSys_Filesize(asMachine e)
{
	auto ptr = (filesystem::path*)asGetLong(asArgument(e, 0));

	return asReturnLong(e, filesystem::file_size(*ptr));
}
asInt System_FSys_Rename(asMachine e)
{
	auto ptr = (filesystem::path*)asGetLong(asArgument(e, 0));
	auto ptrto = (filesystem::path*)asGetLong(asArgument(e, 1));
	filesystem::rename(*ptr, *ptrto);
	return 0;
}
asInt System_FSys_Resize(asMachine e)
{
	auto ptr = (filesystem::path*)asGetLong(asArgument(e, 0));
	asLong size = asGetLong(asArgument(e, 1));
	filesystem::resize_file(*ptr, size);
	return 0;
}
asInt System_FSys_GetTemp(asMachine e)
{
	return asReturnLong(e, (asLong)new auto(filesystem::temp_directory_path()));
}
asInt System_FSys_GetChildPathList(asMachine e)
{
	auto ptr = (filesystem::path*)asGetLong(asArgument(e, 0));
	asLong hwnd = asGetLong(asArgument(e, 1));

	for (auto& p : filesystem::recursive_directory_iterator(*ptr))
	{
		auto cr = asMachineCr(e);
		asSetString(cr, p.path().string().c_str());
		asArrayPush(hwnd, cr);
	}

	return 0;
	//fs::recursive_directory_iterator
}
asInt System_FSys_IsDirectory(asMachine e)
{
	auto ptr = (filesystem::path*)asGetLong(asArgument(e, 0));
	return asReturnInt(e, filesystem::is_directory(*ptr));
	//fs::recursive_directory_iterator
}
asInt System_FSys_GetFileName(asMachine e)
{
	auto ptr = (filesystem::path*)asGetLong(asArgument(e, 0));
	return asReturnString(e, ptr->filename().string().c_str());

	//fs::recursive_directory_iterator
}
asInt System_FSys_GetParentPath(asMachine e)
{
	auto ptr = (filesystem::path*)asGetLong(asArgument(e, 0));
	return asReturnString(e, ptr->parent_path().string().c_str());

	//fs::recursive_directory_iterator
}
asInt System_FSys_GetExtension(asMachine e)
{
	auto ptr = (filesystem::path*)asGetLong(asArgument(e, 0));
	return asReturnString(e, ptr->extension().string().c_str());

	//fs::recursive_directory_iterator
}

asInt System_FSys_Remove(asMachine e)
{
	auto ptr = (filesystem::path*)asGetLong(asArgument(e, 0));

	filesystem::remove(*ptr);

	return 0;

	//fs::recursive_directory_iterator
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
void asInit(asInt ac, char** av)
{
	static std::atomic_bool Flag = false;

	if (Flag)
		return;
	Flag = true;

	AScene::MachineData::PublicTable.clear();
	ARGC = ac;
	ARGV = av;
	ecs::Environment::showConsole = ecs::Environment::__ShowConsole;
	ecs::Environment::Path::ExeFilePath = ecs::Environment::GetProgramDir();
	AScene::AsceneInit();

	asRegister(System_Runtime_FunctionCall, "__stdascene_system_runtime_functioncall");

	asRegister(System_FSys_Openpath, "__stdascene_system_filesys_openpath");
	asRegister(System_FSys_Closepath, "__stdascene_system_filesys_closepath");
	asRegister(System_FSys_ToString, "__stdascene_system_filesys_tostring");
	asRegister(System_FSys_CreateDirectory, "__stdascene_system_filesys_createdirectory");
	asRegister(System_FSys_Exists, "__stdascene_system_filesys_exists");
	asRegister(System_FSys_Copy, "__stdascene_system_filesys_copy");
	asRegister(System_FSys_Remove, "__stdascene_system_filesys_remove");
	asRegister(System_FSys_Filesize, "__stdascene_system_filesys_filesize");
	asRegister(System_FSys_Rename, "__stdascene_system_filesys_rename");
	asRegister(System_FSys_Resize, "__stdascene_system_filesys_resize");
	asRegister(System_FSys_GetTemp, "__stdascene_system_filesys_temppath");
	asRegister(System_FSys_GetChildPathList, "__stdascene_system_filesys_getchildpathlist");
	asRegister(System_FSys_IsDirectory, "__stdascene_system_filesys_isdirectory");
	asRegister(System_FSys_GetFileName, "__stdascene_system_filesys_filename");
	asRegister(System_FSys_GetParentPath, "__stdascene_system_filesys_parentpath");
	asRegister(System_FSys_GetExtension, "__stdascene_system_filesys_extension");



	asRegister(System_Json_StringSaveToFile, "__stdascene_system_file_savetofile_basic");
	asRegister(System_Json_FileReadToStr, "__stdascene_system_file_readfromfile_basic");

	asRegister(System_GetArgs, "__stdascene_system_getargs");

	asRegister(System_Set_VmPath, "__stdascene_system_setvmpath");

	asRegister(System_GetVersion, "__stdascene_system_getversion");

	asRegister(System_File_OpenToRead, "__stdascene_system_file_open_to_read");
	asRegister(System_File_ReadLine, "__stdascene_system_file_readline");
	asRegister(System_File_Close, "__stdascene_system_file_close");

	asRegister(System_Native_Malloc, "__stdascene_system_native_malloc");
	asRegister(System_Native_Free, "__stdascene_system_native_free");
	asRegister(System_Native_Memcpy, "__stdascene_system_native_memcpy");
	asRegister(System_Native_PhaseInt, "__stdascene_system_native_phaseint");
	asRegister(System_Native_PhaseString, "__stdascene_system_native_phasestring");
	asRegister(System_Native_PhaseLong, "__stdascene_system_native_phaselong");
	asRegister(System_Native_PhaseDouble, "__stdascene_system_native_phasedouble");
	asRegister(System_Native_Write, "__stdascene_system_native_write");

	asRegister(System_Thread_Sleep, "__stdascene_system_thread_sleep");
	asRegister(System_Thread_CreateMutex, "__stdascene_system_thread_createmutex");
	asRegister(System_Thread_DestroyMutex, "__stdascene_system_thread_destroymutex");
	asRegister(System_Thread_LockMutex, "__stdascene_system_thread_lockmutex");
	asRegister(System_Thread_ReleaseMutex, "__stdascene_system_thread_releasemutex");

	asRegister(System_Rand_UniformRandInt, "__stdascene_system_rand_int");
	asRegister(System_Rand_UniformRandDouble, "__stdascene_system_rand_double");
}
asMachine asCreateMachine(asInt StackSize)
{
	auto newMechinePtr = StackSize ? new AScene::Machine(StackSize) : new AScene::Machine();
	return newMechinePtr;
}
void asDestroyMachine(asMachine Machine)
{
	//WriteLock;
	/*if (MachineList.find(Machine))
	{
		MachineList.erase(Machine);*/
	if (Machine)
		delete Machine;
	//}
	//std::cout << "???ddd" << std::endl;
}
asInt asLoadSource(asMachine Machine, asString SourceCode)
{
	try
	{
		return Machine->LoadFromString(SourceCode);
	}
	catch (...)
	{
		WriteLock;
		LastErrorInfo = ErrorInfo[Machine] = "ABI compile or compile error.";
		return 1;
	}
	return 0;
}
asInt asLoadFile(asMachine Machine, asString FileName)
{
	try
	{
		return Machine->LoadFromFile(FileName);
	}
	catch (...)
	{
		WriteLock;
		LastErrorInfo = ErrorInfo[Machine] = "ABI compile or compile error.";
		return 1;
	}
	return 0;
}
asString asGetLastError()
{
	ReadLock;
	return LastErrorInfo.data();
}

asString asGetError(asMachine Machine)
{
	ReadLock;
	return ErrorInfo[Machine].data();
}

asValue asRun(asMachine Machine)
{
	/*
	startFrom(machine,"__std__CallMain");
			return run(machine);*/
	try
	{
		if (!Machine->FailSign)
		{
			Machine->SetStartFrom("__std__CallMain");
			Machine->Run();

			return Machine->CalcBuffer->var_Ref;
		}
	}
	catch (AScene::Exception e)
	{
		WriteLock;
		LastErrorInfo = ErrorInfo[Machine] = e.what();
	}
	catch (...)
	{
		WriteLock;
		LastErrorInfo = ErrorInfo[Machine] = "Unknown runtime exception.";
	}
	return nullptr;
}
void asSetDebugFlag(asMachine Machine, asBool flag)
{
	Machine->Debug = flag;
}
asValue asDebugRun(asMachine Machine)
{
	try
	{
		if (!Machine->FailSign)
		{
			Machine->SetStartFrom("__std__CallMain");
			Machine->DebugRun();

			return Machine->CalcBuffer->var_Ref;
		}
	}
	catch (AScene::Exception e)
	{
		WriteLock;
		LastErrorInfo = ErrorInfo[Machine] = e.what();
	}
	catch (...)
	{
		WriteLock;
		LastErrorInfo = ErrorInfo[Machine] = "Unknown runtime exception.";
	}
	return nullptr;
}

asValue asCoroutineRun(asMachine Machine, int RunMaxLines)
{
	try
	{
		if (!Machine->FailSign)
		{
			if (Machine->NextLineNo >= (long long)Machine->ProgramBuffer.size())
			{
				Machine->SetStartFrom("__std__CallMain");
			}

			Machine->CoroutineRun((size_t)RunMaxLines);

			if (Machine->NextLineNo >= (long long)Machine->ProgramBuffer.size())
				return Machine->CalcBuffer->var_Ref;
			else
				return (asValue)0x01;


			return Machine->CalcBuffer->var_Ref;
		}
	}
	catch (AScene::Exception e)
	{
		WriteLock;
		LastErrorInfo = ErrorInfo[Machine] = e.what();
	}
	catch (...)
	{
		WriteLock;
		LastErrorInfo = ErrorInfo[Machine] = "Unknown runtime exception.";
	}
	return nullptr;
}

asInt asGetInt(asValue Value)
{
	Value = Value->var_Ref;
	switch (Value->typeMsg)
	{
		/*case AScene::AllTypeData::IntMsg:
			return Value->var_Int;*/
	case AScene::AllTypeData::LongMsg:
		return (int)Value->var_Long;
	case AScene::AllTypeData::RealMsg:
		return (int)Value->var_Double;
	}
	return 0;
}

//获得ValuePtr索引的long long值
asLong asGetLong(asValue Value)
{
	Value = Value->var_Ref;
	switch (Value->typeMsg)
	{
		/*case AScene::AllTypeData::IntMsg:
			return (long long)Value->var_Int;*/
	case AScene::AllTypeData::LongMsg:
		return Value->var_Long;
	case AScene::AllTypeData::RealMsg:
		return (long long)Value->var_Double;
	}
	return 0;
};

//获得ValuePtr索引的double值
double asGetDouble(asValue Value)
{
	Value = Value->var_Ref;
	switch (Value->typeMsg)
	{
		/*case AScene::AllTypeData::IntMsg:
			return (double)Value->var_Int;*/
	case AScene::AllTypeData::LongMsg:
		return (double)Value->var_Long;
	case AScene::AllTypeData::RealMsg:
		return Value->var_Double;
	}
	return 0;
};

//获得ValuePtr索引的字符串
asString asGetString(asValue Value)
{
	Value = Value->var_Ref;
	thread_local static std::string str_V;
	if (Value->typeMsg == AScene::AllTypeData::StringMsg)
		return Value->var_String.data();
	str_V = ecs::Type::ToString(*Value);
	return str_V.data();

	/*
	if (Value->typeMsg == AScene::AllTypeData::Int)
		return Value->var_String.data();
	if (Value->typeMsg == AScene::AllTypeData::StringMsg)
		return Value->var_String.data();*/
}

//获得ValuePtr索引的成员
asValue asGetMember(asValue Value, asString MemberName)
{
	Value = Value->var_Ref;
	if (Value->typeMsg == AScene::AllTypeData::StructMsg)
		return &Value->getMember(MemberName);
	return nullptr;
}

//设置ValuePtr索引的int值
void asSetInt(asValue Value, asInt AimValue)
{
	*Value = AimValue;
}

//设置ValuePtr索引的long long值
void asSetLong(asValue Value, asLong AimValue)
{
	*Value = AimValue;
}

//设置ValuePtr索引的double值
void asSetDouble(asValue Value, asDouble AimValue)
{
	*Value = AimValue;
}

//设置ValuePtr索引的字符串
void asSetString(asValue Value, asString AimValue)
{
	*Value = AimValue;
}

asEnum asGetType(asValue Value)
{
	Value = Value->var_Ref;
	return Value->typeMsg;
}
void asDisplayLinkError(asMachine Machine)
{
	Machine->DisplayCompileError();
}

void asDisplayRuntimeError(asMachine Machine)
{
	AScene::Exception e(asGetError(Machine));
	Machine->DisplayRuntimeError(e);
}

asString asCopyrightInfo()
{
	return "Powered by AdvancedScene 19. Version 19.6.5. (C)Cinogama Project.";
}

asString asVersion()
{
	return "CINOGAMA_ASCENE_V19_6_JECORE_INSIDE "  __DATE__ " " __TIME__;
}

asValue asGetPublic(asMachine Machine, asString Name)
{
	auto hwnd = Machine->GetPublic(Name);
	if (hwnd)
		return hwnd->var_Ref;
	return nullptr;
}
asValue asFunctionRun(asMachine Machine, asString Name, asInt StaxNum)
{
	//size_t nl = 0;
	try
	{
		if (!Machine->FailSign)
		{
			auto v = Machine->StackButtom;

			auto StartPlace = *Machine->GetPublic(std::string(Name) + "@Function");

			long long ptr = (StartPlace.typeMsg == StartPlace.LongMsg) ? StartPlace.var_Long : (long long)StartPlace.var_Double;
			if (ptr >= (long long)Machine->ProgramBuffer.size() || ptr < 0)
				StartPlace = ptr;
			else
				StartPlace = (int)ptr;

			*Machine->TemC = StaxNum;
			//nl = Machine->NextLineNo;
			AScene::Command cmd(AScene::CommandDataStruct::Call, 0, (long long)&StartPlace, 0, 0);
			Machine->bytecodeRun(&cmd);
			Machine->DestructRun(v);

			AScene::Command cmd2(AScene::CommandDataStruct::PopZero);

			for (int i = 0; i < StaxNum; i++)
				Machine->bytecodeRun(&cmd2);

			return Machine->CalcBuffer->var_Ref;
		}
	}
	catch (AScene::Exception e)
	{
		WriteLock;
		LastErrorInfo = ErrorInfo[Machine] = e.what();
	}
	catch (...)
	{
		WriteLock;
		LastErrorInfo = ErrorInfo[Machine] = "Unknown runtime exception.";
	}

	AScene::Command cmd(AScene::CommandDataStruct::PopZero);
	for (int i = 0; i < StaxNum; i++)
	{
		Machine->bytecodeRun(&cmd);
	}
	//Machine->NextLineNo = nl;
	return nullptr;
}

void asSetRunHandle(asMachine Machine, asLong Handle, asInt StaxNum)
{
	if (!Machine->FailSign)
	{
		AScene::AllTypeData StartPlace = Machine->toFunction(Handle);
		long long ptr = (StartPlace.typeMsg == StartPlace.LongMsg) ? StartPlace.var_Long : (long long)StartPlace.var_Double;
		if (ptr >= (long long)Machine->ProgramBuffer.size() || ptr < 0)
			StartPlace = ptr;
		else
			StartPlace = (int)ptr;

		*Machine->TemC = StaxNum;
		AScene::Command cmd(AScene::CommandDataStruct::Call, 0, (long long)&StartPlace, 0, 0);
		Machine->bytecodeRun(&cmd);
	}
}

asValue asHandleRun(asMachine Machine, asLong Handle, asInt StaxNum)
{
	//size_t nl = 0;
	try
	{
		if (!Machine->FailSign)
		{
			auto v = Machine->StackButtom;

			AScene::AllTypeData StartPlace = Machine->toFunction(Handle);

			long long ptr = (StartPlace.typeMsg == StartPlace.LongMsg) ? StartPlace.var_Long : (long long)StartPlace.var_Double;
			if (ptr >= (long long)Machine->ProgramBuffer.size() || ptr < 0)
				StartPlace = ptr;
			else
				StartPlace = (int)ptr;

			*Machine->TemC = StaxNum;
			//nl = Machine->NextLineNo;
			AScene::Command cmd(AScene::CommandDataStruct::Call, 0, (long long)&StartPlace, 0, 0);
			Machine->bytecodeRun(&cmd);
			Machine->DestructRun(v);

			AScene::Command cmd2(AScene::CommandDataStruct::PopZero);
			for (int i = 0; i < StaxNum; i++)
				Machine->bytecodeRun(&cmd2);

			return Machine->CalcBuffer->var_Ref;
		}
	}
	catch (AScene::Exception e)
	{
		WriteLock;
		LastErrorInfo = ErrorInfo[Machine] = e.what();
	}
	catch (...)
	{
		WriteLock;
		LastErrorInfo = ErrorInfo[Machine] = "Unknown runtime exception.";
	}

	AScene::Command cmd(AScene::CommandDataStruct::PopZero);
	for (int i = 0; i < StaxNum; i++)
		Machine->bytecodeRun(&cmd);
	//Machine->NextLineNo = nl;
	return nullptr;
}
asValue asPushInt(asMachine Machine, asInt Value)
{
	AScene::Command cmd(AScene::CommandDataStruct::PshValConst, Value);
	Machine->bytecodeRun(&cmd);
	return (Machine->StackTop - 1)->var_Ref;
}

//向ASCENE虚拟机的栈内内压一个long long型的值,返回值为在栈中的该值
asValue asPushLong(asMachine Machine, asLong Value)
{
	AScene::Command cmd(AScene::CommandDataStruct::PshValConst, Value);
	Machine->bytecodeRun(&cmd);
	return (Machine->StackTop - 1)->var_Ref;
}

//向ASCENE虚拟机的栈内内压一个double型的值,返回值为在栈中的该值
asValue asPushDouble(asMachine Machine, asDouble Value) {
	AScene::Command cmd(AScene::CommandDataStruct::PshValConst, Value);
	Machine->bytecodeRun(&cmd);
	return (Machine->StackTop - 1)->var_Ref;
}

//向ASCENE虚拟机的栈内内压一个string型的值,返回值为在栈中的该值
asValue asPushString(asMachine Machine, asString Value) {
	AScene::Command cmd(AScene::CommandDataStruct::PshValConst, Value);
	Machine->bytecodeRun(&cmd);
	return (Machine->StackTop - 1)->var_Ref;
}

//向ASCENE虚拟机的栈内内压入另一个Value,返回值为在栈中的该值
asValue asPushValue(asMachine Machine, asValue Value) {
	Value = Value->var_Ref;
	AScene::Command cmd(AScene::CommandDataStruct::PshVal, 0, (long long)Value);
	Machine->bytecodeRun(&cmd);
	return (Machine->StackTop - 1)->var_Ref;
}

//从AScene虚拟机栈中获取数据，第二个参数表示距离，
//其中，负数表示距离栈顶的距离
//0和正数表示距离栈底的距离
asValue asStack(asMachine Machine, asInt Index)
{
	if (Index < 0)
		return (Machine->StackTop + Index)->var_Ref;
	return (Machine->StackButtom + Index)->var_Ref;
}

//从AScene虚拟机栈中弹出一个元素
void asPop(asMachine Machine)
{
	AScene::Command cmd(AScene::CommandDataStruct::PopZero);
	Machine->bytecodeRun(&cmd);
}

void asRegister(asInt(*Function)(asMachine), asString FunctionSign)
{
	if (AScene::MachineData::PublicTable.find(FunctionSign) != AScene::MachineData::PublicTable.end())
		std::cerr << "警告 W0001: （运行时方法）正在注册到全局表的签名:" << FunctionSign << "，在此前已经被注册。" << std::endl;
	AScene::MachineData::PublicTable[FunctionSign] = (AScene::AllTypeData::Long)AScene::PharseCoreFunc((AScene::ASceneCFunction)Function);
}

asLong asArgumentNum(asMachine Machine)
{
	return Machine->GetArgumentNumber();
}

asValue asArgument(asMachine Machine, asInt StaxIndex)
{
	return &Machine->GetArgument(StaxIndex);
}


asInt asReturnInt(asMachine e, asInt v)
{
	return e->Return(v);
}

//该函数是在AScene C/C++函数内使用的函数，用于给调用方返回一个long型值
asInt asReturnLong(asMachine e, asLong v)
{
	return e->Return(v);
}

//该函数是在AScene C/C++函数内使用的函数，用于给调用方返回一个double型值
asInt asReturnDouble(asMachine e, asDouble v)
{
	return e->Return(v);
}

//该函数是在AScene C/C++函数内使用的函数，用于给调用方返回一个string型值
asInt asReturnString(asMachine e, asString v)
{
	return e->Return(v);
}

//该函数是在AScene C/C++函数内使用的函数，用于给调用方返回一个值
asInt asReturnValue(asMachine e, asValue v)
{
	return e->Return(*v);
}

//该函数是在AScene C/C++函数内使用的函数，用于给调用方以引用方式返回一个值
asInt asRefReturnValue(asMachine e, asValue v)
{
	return e->RefReturn(*v);
}

std::function<::asInt(::asMachine)>* PharseCoreFunction(void* ptr)
{
	auto obj = new std::function<::asInt(::asMachine)>((int(*)(::asMachine))ptr);
	return obj;
}

asInt VMStart(asInt argc, char** argv)
{

	asInit(argc, argv);//初始化

	ecs::Environment::showConsole(true);

	if (argc == 1)
	{
		std::cout << asCopyrightInfo() << std::endl;
		std::cout << "Advanced Scene. 用法：" << std::endl;
		std::cout << "AdvancedScene [Source File] <...>" << std::endl;
		std::cout << "可用的选项有：" << std::endl;
		std::cout << "\t" << "-obyc [ByteCodeFile]" << std::endl;
		std::cout << "\t" << "产生字节码文件" << std::endl;
		std::cout << "\t" << "-debug" << std::endl;
		std::cout << "\t" << "以调试模式编译源代码文件" << std::endl;
		std::cout << "\t" << "-cpf" << std::endl;
		std::cout << "\t" << "开启代码性能检查(需要开启debug)" << std::endl;
		std::cout << "\t" << "-limt [time]" << std::endl;
		std::cout << "\t" << "限制程序运行时间,0表示不限制" << std::endl;
		std::cout << "\t" << "-stack [size]" << std::endl;
		std::cout << "\t" << "划定AScene虚拟机的栈空间，默认值是 16384" << std::endl;
		std::cout << "Copyright (C) Cinogama. All Right Reserved." << std::endl;
		std::cout << "按回车键继续";
		getchar();
		return 1;
	}

	using namespace AScene;
	using namespace AScene::CommandDataStruct;

	//std::cout << Machine::expressionCollation("asd ).().)") << std::endl;


	AllTypeData n;

	bool PauseAfterEnd = false;
	bool CompForRun = true;
	bool DebugInfo = false;
	bool DeclearInfoOut = false;
	bool CodeCpf = false;
	bool RunBytecode = false;

	std::string OutPath = "";
	float LimitTime = 0.0f;
	int StackSize = 65536;
	//std::cout << AScene::Machine::SingleLineRPMComplishStackBased("n 1 2 + 3 * =") << std::endl;

	for (int n = 1; n < argc; n++)
	{
		if (argv[n][0] == '-')
		{
			if (argv[n] == std::string("-obyc"))
			{
				CompForRun = false;
				if (n + 1 < argc)
				{
					OutPath = argv[n + 1];
				}
			}
			else if (argv[n] == std::string("-debug"))
			{
				DebugInfo = true;
			}
			else if (argv[n] == std::string("-rbyc"))
			{
				RunBytecode = true;
			}
			else if (argv[n] == std::string("-pause_end"))
			{
				PauseAfterEnd = true;
			}
			else if (argv[n] == std::string("-cpf"))
			{
				CodeCpf = true;
			}
			else if (argv[n] == std::string("-stack"))
			{
				if (n + 1 < argc)
				{
					StackSize = ecs::Type::Parse<int>(argv[n + 1]);
				}
			}
			else if (argv[n] == std::string("-limt"))
			{
				if (n + 1 < argc)
				{
					LimitTime = ecs::Type::Parse<float>(argv[n + 1]);
				}
			}
			else if (argv[n] == std::string("-l"))
			{
				if (n + 1 < argc)
				{
					AScene::MachineData::PublicLibList.push_back(argv[n + 1]);
				}
			}
			else if (argv[n] == std::string("-declear"))
			{

			}
		}
	}

	AScene::Machine a(StackSize);
	a.CodePerformanceFeedback = CodeCpf;
	a.Debug = DebugInfo;

	if (LimitTime != 0.0f)
		std::thread(LimitRun, LimitTime).detach();

	if (argc >= 2)
	{


		try
		{
			if (CompForRun)
			{
				if (RunBytecode ? a.InitBytecodeFromFile(argv[1]) : a.InitFromFile(argv[1]))
				{
					a.SetStartFrom("__std__CallMain");
					if (!a.FailSign)
					{
						if (DebugInfo)
						{
							a.DebugRun();

							if (a.CodePerformanceFeedback)
							{
								size_t disp = 0;
								for (size_t i = 0; i < a.PreABIBuffer.size(); i++)
								{

									if (a.PreABIBuffer[i] == "" || a.PreABIBuffer[i][0] == ':');
									else
									{
										printf("%.2f%%", 100.0f * (float)a.CPF_LineNO_CRT[disp] / (float)a.CPF_RunTotalNumber);
										disp++;
									}
									std::cout << "\t" << a.PreABIBuffer[i] << std::endl;
								}
							}
						}
						else
							a.Run();
					}
				}
			}
			else
			{
				if (a.CompileFromFile(argv[1]))
				{
					std::ofstream NewOutFile(OutPath);
					NewOutFile << "_ASCENEBYTECODE" << std::endl;
					if (NewOutFile.is_open())
					{
						//NewOutFile << "bytecode" << std::endl << "{" << std::endl;
						for (auto& e : a.PreABIBuffer)
						{
							NewOutFile << e << ";" << std::endl;
						}
						//NewOutFile << "}" << std::endl;
						NewOutFile.close();
					}
				}
			}
		}
		catch (AScene::Exception e)
		{
			a.DisplayRuntimeError(e);
		}

	}
	if (PauseAfterEnd && ecs::Environment::GUIShowStage)
		ecs::Environment::pause();
	return (int)a.CalcBuffer->var_Double;
}

#ifdef _DEBUG
int main(int gc, char** gv)
{
	return VMStart(gc, gv);
}
#endif


//从arrayHandle指向的AScene数组中获得第index个元素
asValue asArrayGet(asLong arrayHandle, int index)
{
	return &(*(std::vector<AScene::AllTypeData>*)arrayHandle)[index];
}

//从arrayHandle指向的AScene数组中移除第index个元素
void asArrayErase(asLong arrayHandle, int index)
{
	auto v = (std::vector<AScene::AllTypeData>*)arrayHandle;
	v->erase(v->begin() + index);
}

//将arrayHandle指向的AScene数组大小设为size
void asArrayResize(asLong arrayHandle, int size)
{
	auto v = (std::vector<AScene::AllTypeData>*)arrayHandle;
	v->resize(size);
}

//将arrayHandle指向的AScene数组清空
void asArrayClear(asLong arrayHandle) {
	auto v = (std::vector<AScene::AllTypeData>*)arrayHandle;
	v->clear();
}

//将arrayHandle指向的AScene数组末尾追加元素elem
void asArrayPush(asLong arrayHandle, asValue elem)
{
	elem = elem->var_Ref;
	auto v = (std::vector<AScene::AllTypeData>*)arrayHandle;
	v->push_back(*elem);
}

//获得arrayHandle指向的AScene数组的大小
int asArraySize(asLong arrayHandle)
{
	return (int)((std::vector<AScene::AllTypeData>*)arrayHandle)->size();
}

//获得AScene虚拟机e的运算缓冲寄存器，获取同时会清除寄存器中的引用信息
asValue asMachineCr(asMachine e)
{
	e->CalcBuffer->var_Ref = e->CalcBuffer;
	return e->CalcBuffer;
}

asValue asMachineRc(asMachine e)
{
	e->RefC->var_Ref = e->RefC;
	return e->RefC;
}

void asCopyMachine(asMachine src, asMachine dst)
{
	AScene::MakeCopyMachine(src, dst);
}

void asException(asString exception)
{
	throw AScene::Exception(exception);
}

void asSetTable(asString tableItemName, asValue value)
{
	value = value->var_Ref;
	AScene::MachineData::PublicTable[tableItemName] = *value;
}

asValue asGetTable(asString tableItemName)
{
	return &AScene::MachineData::PublicTable[tableItemName];
}

asValue asTempValue()
{
	thread_local static AScene::AllTypeData dat;

	return &dat;
}
void asParseObject(asValue value)
{
	value = value->var_Ref;
	value->PhaseToObject();
}

void* asGetWeakPtrHwndWithObject(asValue value)
{
	value = value->var_Ref;
	std::weak_ptr<AScene::AllTypeData::Member<AScene::AllTypeData>>* wptr = new
		std::weak_ptr<AScene::AllTypeData::Member<AScene::AllTypeData>>(value->var_Member);
	return wptr;
}
void asSetObjectWithWeakPointer(asValue value, void* wkp)
{
	value = value->var_Ref;
	value->var_Ref = value;
	value->typeMsg = AScene::AllTypeData::StructMsg;
	value->var_Member =
		((std::weak_ptr<AScene::AllTypeData::Member<AScene::AllTypeData>>*) wkp)->lock();
}

void asReleaseWeakPtrHwnd(void* weaker)
{
	delete (std::weak_ptr<AScene::AllTypeData::Member<AScene::AllTypeData>>*) weaker;
}

//获得成员列表指针索引的成员

void asSetValue(asValue dst, asValue src)
{
	*dst = *src;
}

asString asGetLinkError(asMachine e)
{
	e->CalcBuffer->var_Ref = e->CalcBuffer;
	(*e->CalcBuffer) = e->GetLinkError();
	return e->CalcBuffer->var_String.c_str();
}

//获取虚拟机发生的运行时错误信息
asString asGetRuntimeError(asMachine e)
{
	e->CalcBuffer->var_Ref = e->CalcBuffer;
	(*e->CalcBuffer) = e->GetRuntimeError();
	return e->CalcBuffer->var_String.c_str();
}

//获取虚拟机发生的编译时错误信息
asString asGetCompileError(asMachine e)
{
	e->CalcBuffer->var_Ref = e->CalcBuffer;
	(*e->CalcBuffer) = e->GetCompileError();
	return e->CalcBuffer->var_String.c_str();
}

void asAddPackagePath(asString path)
{
	AScene::Machine::PackagePathList.push_back(path);
}

asString asBuildBytecode(asMachine e)
{
	thread_local static std::string result;
	result = "_ASCENEBYTECODE\n";// << std::endl;

	for (auto& e : e->PreABIBuffer)
	{
		result += e + ";\n";
	}

	return result.c_str();
	//NewOutFile << "}" << std::endl;


}

asString asVMPath(asString path)
{
	if (path)
		ecs::Environment::Path::ExeFilePath = path;
	return ecs::Environment::Path::ExeFilePath.c_str();
}